<template>
  <view class="split-screen-container" :style="{ height: containerHeight + 'px' }">
    <view class="content-section top-content" :style="{ height: topHeight + 'px' }">
      <view class="fixed-header">
        <slot name="top-header"></slot>
      </view>
      <scroll-view scroll-y class="scroll-view" :style="{ height: topScrollHeight + 'px' }">
        <slot name="content"></slot>
      </scroll-view>
    </view>
    <view
      class="resize-handle"
      @touchstart.prevent="startResize"
      @touchmove.prevent="resize"
      @touchend.prevent="endResize"
    ></view>
    <view class="content-section bottom-content" :style="{ height: bottomHeight + 'px' }">
      <view class="fixed-header">
        <slot name="bottom-header"></slot>
      </view>
      <scroll-view scroll-y class="scroll-view" :style="{ height: bottomScrollHeight + 'px' }">
        <slot name="pane"></slot>
      </scroll-view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, nextTick } from 'vue'

interface Props {
  min: number
  max: number
  containerHeight: number
}

const props = defineProps<Props>()

const RESIZE_HANDLE_HEIGHT = 20

const topHeight = ref(props.max)
const topHeaderHeight = ref(0)
const bottomHeaderHeight = ref(0)
let startY = 0
let startHeight = 0
let isResizing = false

const minTopHeight = computed(() => props.min)
const maxTopHeight = computed(() => props.containerHeight - props.min - RESIZE_HANDLE_HEIGHT)

const bottomHeight = computed(() => props.containerHeight - topHeight.value - RESIZE_HANDLE_HEIGHT)

const topScrollHeight = computed(() => topHeight.value - topHeaderHeight.value)
const bottomScrollHeight = computed(() => bottomHeight.value - bottomHeaderHeight.value)

onMounted(async () => {
  if (props.containerHeight <= 0) {
    console.error('containerHeight must be a positive number')
    return
  }
  topHeight.value = Math.min(props.max, props.containerHeight - props.min - RESIZE_HANDLE_HEIGHT)

  // Wait for the DOM to update
  await nextTick()

  // Get the heights of the fixed headers
  const topHeaderEl = document.querySelector('.top-content .fixed-header')
  const bottomHeaderEl = document.querySelector('.bottom-content .fixed-header')

  if (topHeaderEl) topHeaderHeight.value = topHeaderEl.getBoundingClientRect().height
  if (bottomHeaderEl) bottomHeaderHeight.value = bottomHeaderEl.getBoundingClientRect().height
})

const startResize = (e: TouchEvent) => {
  isResizing = true
  startY = e.touches[0].clientY
  startHeight = topHeight.value
}

const resize = (e: TouchEvent) => {
  if (!isResizing) return
  const deltaY = e.touches[0].clientY - startY
  let newTopHeight = startHeight + deltaY

  newTopHeight = Math.max(minTopHeight.value, Math.min(newTopHeight, maxTopHeight.value))
  topHeight.value = newTopHeight
}

const endResize = () => {
  isResizing = false
}
</script>

<style scoped lang="scss">
.split-screen-container {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background-color: #f5f5f5;
}

.content-section {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  overflow: hidden;
}

.fixed-header {
  flex-shrink: 0;
}

.scroll-view {
  flex-grow: 1;
  overflow-y: auto;
}

.resize-handle {
  position: relative;
  flex-shrink: 0;
  height: 20px;
  touch-action: none;
  cursor: row-resize;
  background-color: #fff;
  box-shadow:
    0 -4px 6px -1px rgba(0, 0, 0, 0.1),
    0 -2px 4px -1px rgba(0, 0, 0, 0.06);
}

.resize-handle::after {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 40px;
  height: 4px;
  content: '';
  background-color: #ddd;
  border-radius: 2px;
  transform: translate(-50%, -50%);
}

.resize-handle:active {
  background-color: #f0f0f0;
}

.resize-handle:active::after {
  background-color: skyblue;
}
</style>
